export const excel = function(columns, data, FileName, div) {
  const getChild = function(columns) {
    const arr = [];
    for (let i = 0, l = columns.length; i < l; i++) {
      const children = columns[i].children;
      if (children) {
        for (let j = 0; j < children.length; j++) {
          arr.push(children[j]);
        }
      }
    }
    return arr;
  };

  const deepClone = function(obj) {
    let tmp = '';
    let result = '';
    tmp = JSON.stringify(obj);
    result = JSON.parse(tmp);
    return result;
  };

  const getLastChild = function(columns) {
    const ary = [];
    const each = function(data) {
      data.forEach(function(item) {
        if (item.children) {
          each(item.children);
        } else {
          ary.push(item);
        }
      });
    };
    each(columns);
    return ary;
  };

    // 获取表头columns最大层级
  const getMaxFloor = function(treeData) {
    let max = 0;
    const _treeData = deepClone(treeData);
    const each = function(data, floor) {
      data.forEach(function(item) {
        item.floor = floor;
        if (floor > max) {
          max = floor;
        }
        if (item.children) {
          each(item.children, floor + 1);
        }
      });
    };
    each(_treeData, 1);
    return {
      max: max,
      _treeData: _treeData
    };
  };

  const getColspan = function(arr) {
    const ary = [];
    const each = function(data) {
      data.forEach(function(item) {
        ary.push(item);
        if (item.children) {
          each(item.children);
        }
      });
    };
    each(arr);
    return ary.filter(function(item) { return item.children === undefined; }).length;
  };

  const handleColumns = function(columns, max) {
    const _columns = deepClone(columns);
    const each = function(data) {
      data.forEach(function(item) {
        if (item.children) {
          item.colspan = getColspan([item]);
          item.rowspan = 1;
        } else {
          item.colspan = 1;
          item.rowspan = max - item.floor + 1;
        }
        if (item.children) {
          each(item.children);
        }
      });
    };
    each(_columns);
    return _columns;
  };

  const thead = function(columns) {
    const ary = [columns];
    const each = function(data) {
      const arr = getChild(data);
      ary.push(arr);
      if (arr.length) {
        each(arr);
      }
    };
    each(columns);
    return ary;
  };

  const createTd = function(ary) {
    let td = '';
    ary.forEach(function(item) {
      td += '<th colspan="' + item.colspan + '"  rowspan="' + item.rowspan + '">' + item.label + '</th>';
    });

    return td;
  };

    // 设置多级表头

  const createThead = function(columns, max) {
    const theadList = thead(columns).filter(function(item) { return item.length; });
    let tr = '';
    theadList.forEach(function(item, index) {
      if (index === 0) {
        tr += '<tr><th rowspan=' + max + '>序号</th>' + createTd(item) + '</tr>';
      } else {
        tr += '<tr>' + createTd(item) + '</tr>';
      }
    });
    return tr;
  };

    // 设置数据
  const createData = function(data, columns) {
    const lastChild = getLastChild(columns);
    let row = '';
    const th = function(item) {
      let th = '';
      lastChild.forEach(function(v) {
        if (typeof item[v.prop] === 'object') {
          th += '<th style=' + item[v.prop]['style'] + '>' + item[v.prop]['value'] + '</th>';
        } else {
          th += '<th>' + item[v.prop] + '</th>';
        }
      });
      return th;
    };
    data.forEach(function(item, index) {
      row += '<tr><th>' + (++index) + '</th>' + th(item) + '</tr>';
    });

    return row;
  };

  const createTable = function(columns, data) {
    const maxFloor = getMaxFloor(columns);

    const max = maxFloor.max;

    const _treeData = maxFloor._treeData;

    const newColumns = handleColumns(_treeData, max);

    const thead = createThead(newColumns, max);

    const tableData = createData(data, columns);

    const table = '<table id="tab" cellpadding="1" cellspacing="1" border="1">' + thead + tableData + '</table>';

    return table;
  };

  const saveAs = saveAs || (function(view) {
    'use strict';
    // IE <10 is explicitly unsupported
    if (typeof view === 'undefined' || typeof navigator !== 'undefined' && /MSIE [1-9]\./.test(navigator.userAgent)) {
      return;
    }
    const doc = view.document;
    // only get URL when necessary in case Blob.js hasn't overridden it yet
    const get_URL = function() {
      return view.URL || view.webkitURL || view;
    };
    const save_link = doc.createElementNS('http://www.w3.org/1999/xhtml', 'a');
    const can_use_save_link = 'download' in save_link;
    const click = function(node) {
      const event = new MouseEvent('click');
      node.dispatchEvent(event);
    };
    const is_safari = /varructor/i.test(view.HTMLElement) || view.safari;
    const is_chrome_ios = /CriOS\/[\d]+/.test(navigator.userAgent);
    const throw_outside = function(ex) {
      (view.setImmediate || view.setTimeout)(function() {
        throw ex;
      }, 0);
    };
    const force_saveable_type = 'application/octet-stream';
    // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
    const arbitrary_revoke_timeout = 1000 * 40; // in ms
    const revoke = function(file) {
      const revoker = function() {
        if (typeof file === 'string') { // file is an object URL
          get_URL().revokeObjectURL(file);
        } else { // file is a File
          file.remove();
        }
      };
      setTimeout(revoker, arbitrary_revoke_timeout);
    };
    const dispatch = function(filesaver, event_types, event) {
      event_types = [].concat(event_types);
      let i = event_types.length;
      while (i--) {
        const listener = filesaver['on' + event_types[i]];
        if (typeof listener === 'function') {
          try {
            listener.call(filesaver, event || filesaver);
          } catch (ex) {
            throw_outside(ex);
          }
        }
      }
    };
    const auto_bom = function(blob) {
      // prepend BOM for UTF-8 XML and text/* types (including HTML)
      // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
      if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
        return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type });
      }
      return blob;
    };
    const FileSaver = function(blob, name, no_auto_bom) {
      if (!no_auto_bom) {
        blob = auto_bom(blob);
      }
      // First try a.download, then web filesystem, then object URLs
      const filesaver = this;
      const type = blob.type;
      const force = type === force_saveable_type;
      let object_url;
      const dispatch_all = function() {
        dispatch(filesaver, 'writestart progress write writeend'.split(' '));
      };
        // on any filesys errors revert to saving with object URLs
      const fs_error = function() {
        if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
          // Safari doesn't allow downloading of blob urls
          const reader = new FileReader();
          reader.onloadend = function() {
            let url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
            const popup = view.open(url, '_blank');
            if (!popup) view.location.href = url;
            url = undefined; // release reference before dispatching
            filesaver.readyState = filesaver.DONE;
            dispatch_all();
          };
          reader.readAsDataURL(blob);
          filesaver.readyState = filesaver.INIT;
          return;
        }
        // don't create more object URLs than needed
        if (!object_url) {
          object_url = get_URL().createObjectURL(blob);
        }
        if (force) {
          view.location.href = object_url;
        } else {
          const opened = view.open(object_url, '_blank');
          if (!opened) {
            // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
            view.location.href = object_url;
          }
        }
        filesaver.readyState = filesaver.DONE;
        dispatch_all();
        revoke(object_url);
      }
      ;
      filesaver.readyState = filesaver.INIT;
      if (can_use_save_link) {
        object_url = get_URL().createObjectURL(blob);
        setTimeout(function() {
          save_link.href = object_url;
          save_link.download = name;
          click(save_link);
          dispatch_all();
          revoke(object_url);
          filesaver.readyState = filesaver.DONE;
        });
        return;
      }
      fs_error();
    };
    const FS_proto = FileSaver.prototype;
    const saveAs = function(blob, name, no_auto_bom) {
      return new FileSaver(blob, name || blob.name || 'download', no_auto_bom);
    };
      // IE 10+ (native saveAs)
    if (typeof navigator !== 'undefined' && navigator.msSaveOrOpenBlob) {
      return function(blob, name, no_auto_bom) {
        name = name || blob.name || 'download';
        if (!no_auto_bom) {
          blob = auto_bom(blob);
        }
        return navigator.msSaveOrOpenBlob(blob, name);
      };
    }
    FS_proto.abort = function() {};
    FS_proto.readyState = FS_proto.INIT = 0;
    FS_proto.WRITING = 1;
    FS_proto.DONE = 2;
    FS_proto.error =
      FS_proto.onwritestart =
      FS_proto.onprogress =
      FS_proto.onwrite =
      FS_proto.onabort =
      FS_proto.onerror =
      FS_proto.onwriteend =
        null;
    return saveAs;
  }(
    typeof self !== 'undefined' && self ||
      typeof window !== 'undefined' && window ||
      this.content
  ));
  let table = createTable(columns, data);
  table += div;
  let excelFile = "<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' xmlns='http://www.w3.org/TR/REC-html40'>";
  excelFile += '<meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8">';
  excelFile += '<meta http-equiv="content-type" content="application/vnd.ms-excel';
  excelFile += '; charset=UTF-8">';
  excelFile += '<head>';
  excelFile += '<!--[if gte mso 9]>';
  excelFile += '<xml>';
  excelFile += '<x:ExcelWorkbook>';
  excelFile += '<x:ExcelWorksheets>';
  excelFile += '<x:ExcelWorksheet>';
  excelFile += '<x:Name>';
  excelFile += '{worksheet}';
  excelFile += '</x:Name>';
  excelFile += '<x:WorksheetOptions>';
  excelFile += '<x:DisplayGridlines/>';
  excelFile += '</x:WorksheetOptions>';
  excelFile += '</x:ExcelWorksheet>';
  excelFile += '</x:ExcelWorksheets>';
  excelFile += '</x:ExcelWorkbook>';
  excelFile += '</xml>';
  excelFile += '<![endif]-->';
  excelFile += '</head>';
  excelFile += '<body>';
  excelFile += table;
  excelFile += '</body>';
  excelFile += '</html>';

  // saveAs兼容ie
  const blob = new Blob([excelFile], { type: 'application/vnd.ms-' + 'excel' });
  saveAs(blob, FileName + '.' + 'xls');
};
// });

